
/*
 * Dependency: none
**/

if (typeof TVB === "undefined" || !TVB) {
    var TVB = {};
}

TVB.util = {
    namespace: function() {
        var a=arguments, o=window, i, j, d;
        for (i=0; i<a.length; i=i+1) {
            d=(""+a[i]).split(".");
            for (j=0; j<d.length; j=j+1) {
                o[d[j]]=o[d[j]] || {};
                o=o[d[j]];
            }
        }
        return o;
    },
    supplant: function (template, o) { 
        return template.replace(/\{([^{}]*)\}/g, function (a, b) {  
                var r = o[b];
                return typeof r === 'string' ? r : a; 
            }
        ); 
    },
    isSet: function (s) {
        var n, arr, o;
        if (typeof s === "string") {
            arr = s.split(".");
            o = window;
            for (n = (arr[0] === "window") ? 1 : 0; n < arr.length; n += 1) {
                if (typeof o[arr[n]] === "undefined") {
                    return false;
                } else {
                    o = o[arr[n]];
                }
            }
            return true;
        }
        throw new Error("Missing or invalid argument passed to isDefined");
    },
    arrReduce: function (arr, value) {
        var len = arr.length;
        for (var i = 0; i < len; i += 1) {
            if (arr[i] === value) {
                arr.splice(i, 1);
                return true;
            }
        }
        return false;
    },

    /**
     * Delete duplicate items from an array. Can also trim string items, delete empty string items
     * @arr    target array (will be changed, the origenal order will be reserved)
     * @fn     an option function will execute for each array item. like function (val) {return val + 'tails';}.
     * @return a array contains the duplicate item
     * Example: var arr = [1,2,3,2,1,window,'a','c',window,'a'];
     *          var arr2 = [1,1,8,8,9,7,0];
     *          var fn = function (v) {return 'pre_' + v;};
     *          arrUnique(arr); //return [1,2,window,'a'], arr is [1,2,3,window,'a','c'];
     *          arrUnique(arr2); //return [1,8], arr2 is ['pre_1','pre_8','pre_9','pre_7','pre_0'];
     */
    arrUnique: function (arr, fn) {
        var arrSort,
            arrDup = [],
            nMatches,
            value;
        arrSort = arr.slice(0);
        arrSort.sort();
        for (var i = 0, len = arrSort.length; i < len; i += 1) {
            if (arrSort[i] === arrSort[i + 1]) {
                if (arrDup.length ===0 || (arrDup.length > 0 && arrDup[length - 1] !== arrSort[i])) {
                    arrDup.push(arrSort[i]);
                }
            }
        }
        for (var j = 0, len2 = arrDup.length; j < len2; j += 1) {
            nMatches = 0;
            value = arrDup[j];
            for (var k = 0; k < arr.length; k += 1) {
                if (value === arr[k]) {
                    nMatches += 1;
                    if (nMatches > 1) {
                        arr.splice(k, 1);
                        k -= 1;
                    }
                }
            }
        }
        if (fn && (toString.call(fn) === "[object Function]")) {
            for (var m = 0; m < arr.length; m += 1) {
                arr[m] = fn(arr[m]);  
            }
        }
        return arrDup;
    },

    scriptFilter: function (oConditions, fn) {
        var i, n, j, arr, o, b = false;
        if (typeof oConditions === "object") {
            if (oConditions.ids && oConditions.ids.length) {
                for (j = 0; j < oConditions.ids.length; j += 1) {
                    if (typeof oConditions.ids[j] === "string" && document.getElementById(oConditions.ids[j]) !== null) {
                        b = true;
                        break;
                    }
                }
            }
            if (b && oConditions.variables && oConditions.variables.length) {
                for (i = 0; i < oConditions.variables.length; i += 1) {
                    arr = oConditions.variables[i].split(".");
                    o = window;
                    for (n = (arr[0] === "window") ? 1 : 0; n < arr.length; n += 1) {
                        if (typeof o[arr[n]] === "undefined") {
                            b = false;
                            break;
                        } else {
                            o = o[arr[n]];
                        }
                    }
                }
            }
            if (b && Object.prototype.toString.call(fn) === "[object Function]") {
                fn();
            }
        } else {
            throw new Error("Missing or invalid argument passed to scriptFilter");
        }
    },
    isControlKey : function (k) {
        return (k > 8 && k < 46) || (k > 90 && k < 96) || (k > 111 && k < 186);  
    },
    /* Only Convert HTML Reserved Characters to Entities */
    toHtmlEntities : function (str) {
        return str.replace(/[<>&"']/g, function (s) {
            return '&#x' + s.charCodeAt(0).toString(16) + ';';
        });
    },
    /* only call the "fn" function only once even if invoke it multiple times */
    once: function (fn, argus) {
        if (Object.prototype.toString.call(fn) === "[object Function]") {
            if (typeof fn.iInvoke === 'undefined') {
                fn(argus);
                fn.iInvoke = 1;
            }
            fn.iInvoke += 1;
        }
    },
    genId: function (prefix) {
        var prefix = prefix || 'guid_';
        var f = arguments.callee;
        if (typeof f.i === 'undefined') {
            f.i = 0;
            f.t = new Date().getTime();
        }
        f.i += 1;
        return prefix + f.t + '_' + f.i;
    },
    fillForm: function (form, json){
        var els = {},tmp,key,len,setVal,buildEls;
        
        var setVal = function (el, val){
            var tagName = el.tagName.toLowerCase();
            var value = (val === undefined)?'':val;
            switch(tagName){            
                case 'textarea':
                    el.value = value;
                break;
                case 'input':
                    switch (el.type){
                        case 'radio':
                            el.checked = (el.value==value)?true:false;
                        break;
                        case 'checkbox':
                            if(typeof value == 'string'){
                                el.checked = (el.value==value)?true:false;
                            }else{
                                if(!value){ value = []}
                                tmp = false;
                                for(i=0,len=value.length;i<len;i++){
                                    if(el.value==value[i]){tmp = true;break;}
                                }
                                el.checked = tmp;
                            }
                        break;
                        default :
                            el.value = value;
                        break;
                    }
                break;
                case 'select':
                    len = el.options.length;
                    for(i=0; i<len; i++){
                        el.options[i].selected = (el.options[i].value==value)?true:false;
                    }
                break;
            }
        }; 
        
        var buildEls = function (arr){
            var name,j=0;
            for(i in arr){
                name = arr[i].name;
                if(name!=''){
                    els[name+'_'+j] = arr[i];
                    j++;
                }
                
            }
        };
        
        buildEls(form.getElementsByTagName("input"));
        buildEls(form.getElementsByTagName("select"));
        buildEls(form.getElementsByTagName("textarea"));
        
        for(i in els){
            tmp = els[i];
            if( !i || !tmp.tagName){ continue; }
            key = i.replace(/\_\d+$/,'').replace(/\[.*\]$/,'');
            setVal(tmp, json[key]);
        }
               
    },
    saveUrlInSession: function () {
        window.name = location.href;	
    },
    getUrlInSession: function () {
        return window.name;	
    }
};
